﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Xml;
using System.Data.OleDb;
using System.Runtime.InteropServices;
using System.Linq;
using DevComponents.DotNetBar;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using PlanningGIS.Framework;
using PlanningGIS.Win.Controls;
using PlanningGIS.Util.Management;
using PlanningGIS.Util.Win32;
using PlanningGIS.ArcGIS;
using PlanningGIS.Framework.Config;
using PlanningGIS.Framework.Rule;
using PlanningGIS.Util.Log;

namespace PlanningGIS.Framework.Controls
{
    /// <summary>
    /// 查询窗体
    /// </summary>
    public partial class FrmQuery : Office2007Form
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public FrmQuery()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 地图
        /// </summary>
        private IMap m_Map;

        /// <summary>
        /// 默认加载选择集
        /// </summary>
        private bool showSelect = true;

        /// <summary>
        /// 查询条件数组
        /// </summary>
        private string[] selectMethodArray = { "<最上图层>", "<可见图层>", "<可选图层>", "<所有图层>" };

        /// <summary>
        /// 窗体实例
        /// </summary>
        private static FrmQuery mInstance;

        /// <summary>
        /// 默认加载选择集
        /// </summary>
        public bool DefaultShowSelect
        {
            get { return showSelect; }
            set
            {
                showSelect = value;
            }
        }

        /// <summary>
        /// 创建实例
        /// </summary>
        /// <returns></returns>
        public static FrmQuery Instance()
        {
            if (mInstance == null || mInstance.IsDisposed)
            {
                mInstance = new FrmQuery();
            }
            return mInstance;
        }

        /// <summary>
        /// 
        /// </summary>
        IHookHelper mHookHelper = new HookHelperExClass();

        /// <summary>
        /// 节点窗体
        /// </summary>
        FrmPtsCoord m_frmPts;

        /// <summary>
        /// FCode只读名称
        /// </summary>
        private string fcodeFieldName = "";

        /// <summary>
        /// 查询的空间对象
        /// </summary>
        public IGeometry SelectGeometry { get; set; }

        /// <summary>
        /// 应用程序框架
        /// </summary>
        IApplication m_Application = null;

        /// <summary>
        /// 应用程序框架
        /// </summary>
        public IApplication Application
        {
            set
            {
                m_Application = value;                
                trvwFeatures.Nodes.Clear();
                dataGridViewX1.Rows.Clear();
                mHookHelper.Hook = m_Application;
                m_Map = mHookHelper.FocusMap;
            }
        }

        /// <summary>
        /// 加载窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmQuery_Load(object sender, EventArgs e)
        {
            try
            {
                RegEvent();
                layersComboBox1.NodesExpand = selectMethodArray;
                layersComboBox1.CompositeLayerEnabled = true;
                layersComboBox1.OnCreate((m_Application as IFramework).Object);
                layersComboBox1.SelectedIndex = 0;

                //added by sheng at 2014-08-04 新增分类代码的Tooltip提示
                //if (!String.IsNullOrWhiteSpace(AppConfig.SystemConfig.基本信息.库体方案))
                //{
                //    ruleName = AppConfig.SystemConfig.基本信息.库体方案;
                //    dataImpRule = RuleConfig.rulesXmlContainer.dataImportRules.Where(p => (p.RuleName == ruleName)).Single();
                //}

                if (!String.IsNullOrWhiteSpace(AppConfig.SystemConfig.常用字段.分类代码))
                {
                    fcodeFieldName = AppConfig.SystemConfig.常用字段.分类代码;
                }
                if (DefaultShowSelect)
                {
                    ShowSelect();
                }               
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// 注册事件
        /// </summary>
        private void RegEvent()
        {
            //(m_Application as IFramework).TOCControl.LabelEdit = esriTOCControlEdit.esriTOCControlManual;
            //ITOCControlEvents_Event pTocEvent = (m_Application as IFramework).TOCControl as ITOCControlEvents_Event;
            //pTocEvent.OnEndLabelEdit += new ITOCControlEvents_OnEndLabelEditEventHandler(pTocEvent_OnEndLabelEdit);
            //mAllLayerCollection = GetAllQueryLayer(m_pMap);
            //InitComboxLayer();
        }

        /// <summary>
        /// 设置当前选择的图层
        /// </summary>
        /// <param name="pLayer"></param>
        public void SetCurrentLayer(ILayer pLayer)
        {
            layersComboBox1.SelectedLayer = pLayer;
        }

        /// <summary>
        /// 刷新选择的图层树
        /// </summary>
        public void RefreshTreeView()
        {
            trvwFeatures.Nodes.Clear();
            dataGridViewX1.Rows.Clear();
            try
            {
                dynamic layers;
                bool istop = false;
                switch (layersComboBox1.Text)
                {
                    case "<最上图层>":
                        layers = MapHelper.GetAllLayer(m_Map);
                        istop = true;
                        break;
                    case "<可见图层>":
                        layers = MapHelper.GetVisibleLayers<IFeatureLayer>(m_Map);
                        break;
                    case "<可选图层>":
                        layers = MapHelper.GetSelectableLayers(m_Map);
                        break;
                    case "<所有图层>":
                        layers = MapHelper.GetAllLayer(m_Map);
                        break;
                    default:
                        layers = new List<ILayer>() { layersComboBox1.SelectedLayer };
                        break;
                }
                IArray arrayAll = new ESRI.ArcGIS.esriSystem.Array();
                foreach (var lyr in layers)
                {
                    ILayer layer = lyr as ILayer;
                    IArray array = QueryHelper.IdentifyLayer(layer, SelectGeometry);
                    if (array == null || array.Count == 0)
                    {
                        //if (istop) break;
                        continue;
                    }
                    string name = layer.Name;
                    if (layer is IFeatureLayer) name = ((layer as IFeatureLayer).FeatureClass as IDataset).Name;
                    TreeNode node = trvwFeatures.Nodes.Add(layer.Name + "(" + array.Count + ")");
                    try
                    {
                        IArray tmp = new ESRI.ArcGIS.esriSystem.Array();
                        for (int i = 0; i < array.Count; i++)
                        {
                            IIdentifyObj oIdentifyObj = array.get_Element(i) as IIdentifyObj;
                            if (oIdentifyObj is IRowIdentifyObject)
                            {
                                IRowIdentifyObject pRowIdentifyObj = oIdentifyObj as IRowIdentifyObject;
                                IFeature pFeature = pRowIdentifyObj.Row as IFeature;
                                node.Nodes.Add(pFeature.OID.ToString());
                                tmp.Add(pFeature);
                            }
                            else if (oIdentifyObj is IRasterIdentifyObj)
                            {
                                IRasterIdentifyObj pRasterIdentifyObj = oIdentifyObj as IRasterIdentifyObj;
                                node.Nodes.Add(pRasterIdentifyObj.Name);
                                tmp.Add(pRasterIdentifyObj.Location);
                            }
                        }
                        arrayAll.Add(tmp);
                        node.Tag = new SelectLayerNode() { Features = tmp, Layer = layer, Name = name };                        
                    }
                    catch (System.Exception ex)
                    {
                        LogHelper.WriteLog(ex);
                    }
                    if (istop) break;
                }
                FlashShapes(arrayAll);
                if (trvwFeatures.Nodes.Count > 0)
                {
                    trvwFeatures.Nodes[0].Expand();
                    if (trvwFeatures.Nodes[0].Nodes.Count > 0)
                    {
                        ShowProperty(trvwFeatures.Nodes[0].Nodes[0]);
                    }
                }
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
            finally
            {
                if (SelectGeometry != null)
                {
                    Marshal.ReleaseComObject(SelectGeometry);
                    SelectGeometry = null;
                }
                this.Focus();
            }
        }

        /// <summary>
        /// flash all feature objects and geometry object( IPoint) in an array
        /// </summary>
        /// <param name="array"></param>
        private void FlashShapes(IArray array)
        {
            try
            {
                IHookActions pHookActions = mHookHelper as IHookActions;
                if (pHookActions != null)
                {
                    if (pHookActions.get_ActionSupportedOnMultiple(array, esriHookActions.esriHookActionsFlash))
                    {
                        pHookActions.DoActionOnMultiple(array, esriHookActions.esriHookActionsFlash);
                    }
                }
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// flash single shape
        /// </summary>
        /// <param name="node"></param>
        private void FlashShape(TreeNode node)
        {
            if (node == null) return;
            if (node.Parent == null) return;
            if (!(node.Parent.Tag is SelectLayerNode)) return;
            int index = node.Parent.Nodes.IndexOf(node);
            IArray pArray = (node.Parent.Tag as SelectLayerNode).Features;
            object obj = pArray.get_Element(index);
            IHookActions pHookActions = mHookHelper as IHookActions;
            if (pHookActions != null)
            {
                if (obj is IFeature)
                {
                    pHookActions.DoAction(((IFeature)obj).Shape, esriHookActions.esriHookActionsFlash);
                }
                else if (obj is IPoint)
                {
                    pHookActions.DoAction(obj, esriHookActions.esriHookActionsFlash);
                }
            }

        }

        /// <summary>
        /// 窗体大小改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmQuery2_ResizeEnd(object sender, EventArgs e)
        {
            dataGridViewX1.Columns[0].Width = (int)(dataGridViewX1.Width * 0.4) - 2;
            dataGridViewX1.Columns[1].Width = (int)(dataGridViewX1.Width * 0.6);
        }

        /// <summary>
        /// 点击树控件显示信息列表缩放至
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tMenuZoomTo_Click(object sender, EventArgs e)
        {
            if (trvwFeatures.SelectedNode == null) return;
            ZoomToGeometry(trvwFeatures.SelectedNode);
        }

        /// <summary>
        /// 移动至
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tMenuPanTo_Click(object sender, EventArgs e)
        {
            if (trvwFeatures.SelectedNode == null) return;
            PanToGeometry(trvwFeatures.SelectedNode);
        }

        /// <summary>
        /// zoom to a single geometry or a collection of geometries
        /// </summary>
        /// <param name="node"></param>
        private void ZoomToGeometry(TreeNode node)
        {
            if (node == null) return;
            IHookActions hookActions = mHookHelper as IHookActions;
            if (hookActions == null) return;
            IArray array = null;
            if (node.Parent == null)
            {
                if (node.Tag is SelectLayerNode)
                {
                    array = (node.Tag as SelectLayerNode).Features;
                    if (array.Count == 0) return;
                    if (!(array.get_Element(0) is IFeature)) return;
                    IArray arrayGeometry = new ESRI.ArcGIS.esriSystem.Array();
                    int index = 0;
                    while (index < array.Count)
                    {
                        if (array.get_Element(index) is IFeature)
                        {
                            arrayGeometry.Add(((IFeature)array.get_Element(index)).Shape);
                        }
                        index++;
                    }
                    if (hookActions.get_ActionSupportedOnMultiple(arrayGeometry, esriHookActions.esriHookActionsZoom))
                    {
                        hookActions.DoActionOnMultiple(arrayGeometry, esriHookActions.esriHookActionsZoom);
                    }
                }
            }
            else
            {
                if (node.Parent.Tag is SelectLayerNode)
                {
                    int index = node.Parent.Nodes.IndexOf(node);
                    array = (node.Parent.Tag as SelectLayerNode).Features;
                    object obj = array.get_Element(index);
                    if (obj is IFeature)
                    {
                        hookActions.DoAction(((IFeature)obj).Shape, esriHookActions.esriHookActionsZoom);
                    }
                    else
                    {
                        hookActions.DoAction(obj, esriHookActions.esriHookActionsZoom);
                    }
                }
            }
        }

        /// <summary>
        /// pan to a single geometry or a collection of geometries
        /// </summary>
        /// <param name="node"></param>
        private void PanToGeometry(TreeNode node)
        {
            if (node == null) return;
            IHookActions pHookActions = mHookHelper as IHookActions;
            if (pHookActions == null) return;
            IArray pArray = null;
            if (node.Parent == null)
            {
                if (node.Tag is SelectLayerNode)
                {
                    pArray = (node.Tag as SelectLayerNode).Features;
                    if (pArray.Count == 0) return;
                    if (!(pArray.get_Element(0) is IFeature)) return;
                    IArray pArrayGeometry = new ESRI.ArcGIS.esriSystem.Array();
                    int index = 0;
                    while (index < pArray.Count)
                    {
                        if (pArray.get_Element(index) is IFeature)
                        {
                            pArrayGeometry.Add(((IFeature)pArray.get_Element(index)).Shape);
                        }
                        index++;
                    }
                    if (pHookActions.get_ActionSupportedOnMultiple(pArrayGeometry, esriHookActions.esriHookActionsPan))
                    {
                        pHookActions.DoActionOnMultiple(pArrayGeometry, esriHookActions.esriHookActionsPan);
                    }
                }
            }
            else
            {
                if (node.Parent.Tag is SelectLayerNode)
                {
                    int index = node.Parent.Nodes.IndexOf(node);
                    pArray = (node.Parent.Tag as SelectLayerNode).Features;
                    object obj = pArray.get_Element(index);
                    if (obj is IFeature)
                    {
                        pHookActions.DoAction(((IFeature)obj).Shape, esriHookActions.esriHookActionsPan);
                    }
                    else
                    {
                        pHookActions.DoAction(obj, esriHookActions.esriHookActionsPan);
                    }
                }
            }
        }

        /// <summary>
        /// 创建选择图层
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuCreateLyr_Click(object sender, EventArgs e)
        {
            try
            {
                if (trvwFeatures.SelectedNode == null || !(trvwFeatures.SelectedNode.Tag is SelectLayerNode) || !((trvwFeatures.SelectedNode.Tag as SelectLayerNode).Layer is IFeatureLayer)) return;

                TreeNode pNode = trvwFeatures.SelectedNode;
                IFeatureLayer pFeatureLyr = (pNode.Tag as SelectLayerNode).Layer as IFeatureLayer;
                IFeatureLayerDefinition pLyrDef = pFeatureLyr as IFeatureLayerDefinition;
                IFeatureLayer pCreateLyr = pLyrDef.CreateSelectionLayer(pNode.Text + "选择图层", true, "", "");
                //设置可见比例尺
                pCreateLyr.MinimumScale = pFeatureLyr.MinimumScale;
                pCreateLyr.MaximumScale = pFeatureLyr.MaximumScale;
                //设置Renderer
                if (pCreateLyr is IGeoFeatureLayer)
                {
                    IGeoFeatureLayer pGeoLyr = pFeatureLyr as IGeoFeatureLayer;
                    IFeatureRenderer pRender = pGeoLyr.Renderer;
                    pGeoLyr = pCreateLyr as IGeoFeatureLayer;
                    pGeoLyr.Renderer = pRender;
                }
                m_Map.AddLayer(pCreateLyr);
                MsgHelper.ShowInfomationMsgbox("根据选择集创建新图层成功!");
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
        }

        /// <summary>
        /// tree node clik
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeViewHitTestInfo pHitInfo = trvwFeatures.HitTest(e.X, e.Y);
            if (pHitInfo == null) return;
            if (pHitInfo.Node == null) return;
            if (pHitInfo.Location != TreeViewHitTestLocations.Label) return;

            if (e.Button == MouseButtons.Right)
            {
                trvwFeatures.SelectedNode = e.Node;
                if (e.Node.Parent == null)  //right click the layer node,flash
                {
                    cMenuFeat.Show(trvwFeatures, e.X, e.Y);
                }
                else    //right click the feature node,flash and show feature property
                {
                    cMenuFeat.Show(trvwFeatures, e.X, e.Y);
                }
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (e.Node == trvwFeatures.SelectedNode)
                {
                    treeView1_AfterSelect(trvwFeatures, new TreeViewEventArgs(e.Node, TreeViewAction.ByMouse));
                }

            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Parent == null)  //left click the layer node,flash
            {
                tsbShowPtsCoord.Enabled = false;
                if (e.Node.Tag is SelectLayerNode)
                {
                    FlashShapes((e.Node.Tag as SelectLayerNode).Features);
                }
            }
            else    //left click the feature node,flash and show feature property
            {
                tsbShowPtsCoord.Enabled = true;
                ShowProperty(e.Node);
                FlashShape(e.Node);

                int index = trvwFeatures.SelectedNode.Parent.Nodes.IndexOf(trvwFeatures.SelectedNode);
                IArray pArray = (trvwFeatures.SelectedNode.Parent.Tag as SelectLayerNode).Features;
                IFeature feature = pArray.get_Element(index) as IFeature;

                if (m_frmPts != null && m_frmPts.IsDisposed == false && m_frmPts.Visible)
                {
                    m_frmPts.Hook = (m_Application as IFramework).MapControl.Object;
                    m_frmPts.Geometry = feature.Shape;
                    m_frmPts.ShowCoordinates();
                }
            }
        }

        /// <summary>
        /// 双击节点定位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Parent == null) return;
            try
            {
                ZoomToGeometry(e.Node);          
            }
            catch (Exception ex)
            {
                MsgHelper.ShowErrorMsgbox(this,ex.Message);
            }
                
        }
        /// <summary>
        /// 缩放至选择集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tMenuZoomToSelectionSet_Click(object sender, EventArgs e)
        {
            if (trvwFeatures.SelectedNode == null || !(trvwFeatures.SelectedNode.Tag is SelectLayerNode) || !((trvwFeatures.SelectedNode.Tag as SelectLayerNode).Features is IArray)) return;
            ZoomToGeometry(trvwFeatures.SelectedNode);

        }
        
        /// <summary>
        /// 导出数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbExpData_Click(object sender, EventArgs e)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                if (trvwFeatures.Nodes.Count == 0) return;
                saveFileDialog1.Filter = "File GeoDatabase(*.gdb)|*.gdb|Personal GeoDatabase(*.mdb)|*.mdb|xml文件(*.xml)|*.xml|Excel文件(*.xls)|*.xls|Access文件(*.mdb)|*.mdb";
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    string strFile = saveFileDialog1.FileName;
                    bool blnSuccess = false;
                    switch (saveFileDialog1.FilterIndex)
                    {
                        case 1:
                        case 2:
                            {
                                blnSuccess = Export(strFile);
                                break;
                            }
                        case 3:
                            {
                                blnSuccess = Export2Xml(strFile);
                                break;
                            }
                        case 4:
                            {
                                blnSuccess = Export2Excel(strFile);
                                break;
                            }
                        case 5:
                            {
                                blnSuccess = ExportPro2Mdb(strFile);
                                break;
                            }
                        default:
                            {
                                break;
                            }
                    }
                    if (blnSuccess)
                    {
                        MsgHelper.ShowInfomationMsgbox("导出成功!");
                    }
                    else
                    {
                        MsgHelper.ShowInfomationMsgbox("导出失败!");
                    }
                }
            }
            catch (System.Exception ex)
            {
                MsgHelper.ShowErrorMsgbox("导出失败!"+ex.Message);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strTargetFile"></param>
        /// <returns></returns>
        private bool Export(string strTargetFile)
        {
            bool blnSuccess = false;
            if (strTargetFile == null || strTargetFile == "") return false;
            if (trvwFeatures.Nodes.Count == 0) return false;
            IWorkspace pWs = PlanningGIS.ArcGIS.WorkspaceHelper.CreateOrOpenWorksapce(strTargetFile);
            if (pWs == null) return false;
            IFeatureWorkspace pFwks = pWs as IFeatureWorkspace;
            if (pFwks == null) return false;
            IWorkspaceEdit pWksEdit = pFwks as IWorkspaceEdit;
            pWksEdit.StartEditing(true);
            pWksEdit.StartEditOperation();
            //IDataset pDataset;
            IFeatureClass pSrcFcls = null;
            IFeatureClass pTargetFcls = null;
            IFeature pSrcFeature;
            IFeatureCursor pTargetFCursor = null;
            IFeatureBuffer pFeatureBuffer = null;

            IArray pArray;
            foreach (TreeNode pNode in trvwFeatures.Nodes)
            {
                if (pNode.Nodes.Count == 0) continue;
                if (!(pNode.Tag is SelectLayerNode)) continue;
                pArray = (pNode.Tag as SelectLayerNode).Features;
                if (pArray.Count == 0) continue;
                if (!(pArray.get_Element(0) is IFeature)) continue;
                int index = 0;
                while (index < pArray.Count)
                {
                    pSrcFeature = pArray.get_Element(index) as IFeature;
                    if (index == 0)
                    {
                        pSrcFcls = pSrcFeature.Class as IFeatureClass;
                        if (!(pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation || pSrcFcls.FeatureType == esriFeatureType.esriFTSimple)) continue;

                        pTargetFcls = CreateFeatureClass(pFwks, pSrcFcls);
                        if (pTargetFcls == null) continue;
                    }
                    // System.Windows.Forms.Application.DoEvents();
                    if (pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation)
                    {
                        pTargetFCursor = pTargetFcls.Insert(true);
                        pFeatureBuffer = pTargetFcls.CreateFeatureBuffer();
                        IAnnotationFeature pSrcAnnoFeature = pSrcFeature as IAnnotationFeature;
                        IAnnotationFeature pTargetAnnoFeature = pFeatureBuffer as IAnnotationFeature;
                        ITextElement pTxtElement = new TextElement() as ITextElement;
                        pTxtElement.Text = ((ITextElement)pSrcAnnoFeature.Annotation).Text;
                        IElement pElement = pTxtElement as IElement;
                        pElement.Geometry = pSrcFeature.Shape.Envelope.LowerLeft;
                        pTxtElement.Symbol = ((ITextElement)pSrcAnnoFeature.Annotation).Symbol;
                        pTxtElement.Symbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
                        pTxtElement.Symbol.VerticalAlignment = esriTextVerticalAlignment.esriTVACenter;
                        pTargetAnnoFeature.Annotation = pTxtElement as IElement;
                        pTargetFCursor.InsertFeature(pFeatureBuffer);
                    }
                    else
                    {
                        pTargetFCursor = pTargetFcls.Insert(true);
                        pFeatureBuffer = pTargetFcls.CreateFeatureBuffer();

                        pFeatureBuffer.Shape = pSrcFeature.ShapeCopy;

                        for (int i = 0; i < pSrcFeature.Fields.FieldCount; i++)
                        {
                            if (pSrcFeature.Fields.get_Field(i).Type != esriFieldType.esriFieldTypeGeometry)
                            {
                                int j = pFeatureBuffer.Fields.FindField(pSrcFeature.Fields.get_Field(i).Name);
                                if (j >= 0)
                                {
                                    if (pFeatureBuffer.Fields.get_Field(j).Editable)
                                    {
                                        if (Convert.IsDBNull(pSrcFeature.get_Value(i)) == false)
                                        {
                                            pFeatureBuffer.set_Value(j, pSrcFeature.get_Value(i));
                                        }
                                    }
                                }
                            }
                        }

                        pTargetFCursor.InsertFeature(pFeatureBuffer);
                    }
                    index++;
                }//end while
                pTargetFCursor.Flush();
                blnSuccess = true;
                Marshal.ReleaseComObject(pTargetFCursor);
                pTargetFCursor = null;

                Marshal.ReleaseComObject(pFeatureBuffer);
                pFeatureBuffer = null;
            }
            pWksEdit.StopEditOperation();
            pWksEdit.StopEditing(true);

            return blnSuccess;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strFile"></param>
        /// <returns></returns>
        private bool Export2Xml(string strFile)
        {
            IFeature pSrcFeature;
            IFeatureClass pSrcFcls = null;
            IArray pArray;
            XmlDocument pXmlDoc = new XmlDocument();   
            //XmlDataDocument pXmlDoc = new XmlDataDocument();
            XmlElement pXmlElement = pXmlDoc.CreateElement("Features");

            pXmlDoc.AppendChild(pXmlElement);
            XmlElement pNodeFcls = null;
            XmlElement pNodeFeature = null;
            IField pFld;
            foreach (TreeNode pNode in trvwFeatures.Nodes)
            {
                if (pNode.Nodes.Count == 0) continue;
                if (!(pNode.Tag is SelectLayerNode)) continue;
                pArray = (pNode.Tag as SelectLayerNode).Features;
                if (pArray.Count == 0) continue;
                if (!(pArray.get_Element(0) is IFeature)) continue;
                int index = 0;
                while (index < pArray.Count)
                {
                    pSrcFeature = pArray.get_Element(index) as IFeature;
                    if (index == 0)
                    {
                        pSrcFcls = pSrcFeature.Class as IFeatureClass;
                        if (!(pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation || pSrcFcls.FeatureType == esriFeatureType.esriFTSimple)) continue;
                        pNodeFcls = pXmlDoc.CreateElement("要素类");
                        pNodeFcls.Attributes.Append(pXmlDoc.CreateAttribute("名称"));
                        pNodeFcls.Attributes[0].Value = ((IDataset)pSrcFcls).Name;
                        pNodeFcls.Attributes.Append(pXmlDoc.CreateAttribute("别名"));
                        pNodeFcls.Attributes[0].Value = pSrcFcls.AliasName;
                        pXmlElement.AppendChild(pNodeFcls);
                    }
                    pNodeFeature = pXmlDoc.CreateElement("要素");
                    pNodeFcls.AppendChild(pNodeFeature);
                    for (int iFld = 0; iFld < pSrcFeature.Fields.FieldCount; iFld++)
                    {
                        pFld = pSrcFcls.Fields.get_Field(iFld);
                        if (
                            pFld.Type != esriFieldType.esriFieldTypeBlob
                            & pFld.Type != esriFieldType.esriFieldTypeGeometry
                            & pFld.Type != esriFieldType.esriFieldTypeRaster)
                        {
                            XmlAttribute pAttribute = pXmlDoc.CreateAttribute(pFld.AliasName == "" ? pFld.Name : pFld.AliasName);
                            pAttribute.Value = pSrcFeature.get_Value(iFld) == null ? "" : pSrcFeature.get_Value(iFld).ToString();
                            pNodeFeature.Attributes.Append(pAttribute);

                        }
                    }
                    index++;
                }//end while                             
            }
            pXmlDoc.Save(strFile);
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strFile"></param>
        /// <returns></returns>
        private bool Export2Excel(string strFile)
        {
            string strPath;
            if (OSHelper.CheckExcel(out strPath) == false)
            {
                MsgHelper.ShowErrorMsgbox("检测到您的电脑上未安装2003或以上版本的Excel!");
                return false;
            }
            IFeature pSrcFeature;
            IFeatureClass pSrcFcls = null;
            IArray pArray;
            IField pFld;
            System.IO.FileInfo fi = new System.IO.FileInfo(strFile);
            try
            {
                if (fi.Exists)
                    fi.Delete();
            }
            catch (System.Exception)
            {
                MsgHelper.ShowErrorMsgbox("导出出错!");
                return false;
            }
            ComObject pExcel = ComObject.CreateComInstance("Excel.Application");
            ComObject pWorkBooks = ComObject.CreateInstance(pExcel["Workbooks"]);
            ComObject pWorkbook = ComObject.CreateInstance(pWorkBooks.InvokeMethod("Add"));
            ComObject pWorkSheets = ComObject.CreateInstance(pWorkbook["Worksheets"]);
            ComObject pWorkSheet = null;
            int iSheetCol;
            int iWorkSheet = 0;
            foreach (TreeNode pNode in trvwFeatures.Nodes)
            {
                if (pNode.Nodes.Count == 0) continue;
                if (!(pNode.Tag is SelectLayerNode)) continue;
                pArray = (pNode.Tag as SelectLayerNode).Features;
                if (pArray.Count == 0) continue;
                if (!(pArray.get_Element(0) is IFeature)) continue;
                iWorkSheet++;
                int index = 0;
                while (index < pArray.Count)
                {
                    pSrcFeature = pArray.get_Element(index) as IFeature;
                    if (index == 0)
                    {
                        pSrcFcls = pSrcFeature.Class as IFeatureClass;
                        if (!(pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation || pSrcFcls.FeatureType == esriFeatureType.esriFTSimple)) continue;

                        if (iWorkSheet > (int)pWorkSheets["Count"])
                        {
                            pWorkSheet = ComObject.CreateInstance(pWorkSheets.InvokeMethod("Add", System.Reflection.Missing.Value, System.Reflection.Missing.Value, 1, 4));
                        }
                        else
                        {
                            pWorkSheet = ComObject.CreateInstance(pWorkbook["Worksheets", iWorkSheet]);
                        }
                        pWorkSheet["Name"] = ((IDataset)pSrcFcls).Name;
                        iSheetCol = 0;
                        for (int iFld = 0; iFld < pSrcFcls.Fields.FieldCount; iFld++)
                        {
                            pFld = pSrcFcls.Fields.get_Field(iFld);
                            if (
                                pFld.Type != esriFieldType.esriFieldTypeBlob
                                & pFld.Type != esriFieldType.esriFieldTypeGeometry
                                & pFld.Type != esriFieldType.esriFieldTypeRaster)
                            {
                                iSheetCol++;
                                ComObject pRange = ComObject.CreateInstance(pWorkSheet["Cells", 1, iSheetCol]);
                                pRange["Value2"] = pFld.AliasName == "" ? pFld.Name : pFld.AliasName;
                            }
                        }
                    }
                    iSheetCol = 0;
                    for (int iFld = 0; iFld < pSrcFeature.Fields.FieldCount; iFld++)
                    {
                        pFld = pSrcFcls.Fields.get_Field(iFld);
                        if (
                            pFld.Type != esriFieldType.esriFieldTypeBlob
                            & pFld.Type != esriFieldType.esriFieldTypeGeometry
                            & pFld.Type != esriFieldType.esriFieldTypeRaster)
                        {
                            iSheetCol++;
                            ComObject pRange = ComObject.CreateInstance(pWorkSheet["Cells", index + 2, iSheetCol]);
                            pRange["Value2"] = pSrcFeature.get_Value(iFld) == null ? "" : pSrcFeature.get_Value(iFld).ToString();
                        }
                    }
                    index++;
                }//end while     

            }
            SaveAs(strFile, pWorkbook);
            pExcel.InvokeMethod("Quit");
            return true;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strFile"></param>
        /// <returns></returns>
        private bool ExportPro2Mdb(string strFile)
        {

            OleDbConnection conn = null;
            try
            {
                if (System.IO.File.Exists(strFile)) System.IO.File.Delete(strFile);
                conn = CreateMDB(strFile);
                conn.Open();
            }
            catch (System.Exception)
            {
                MsgHelper.ShowErrorMsgbox("导出出错!");
                return false;
            }
            IFeature pSrcFeature;
            IFeatureClass pSrcFcls = null;
            IArray pArray;
            //IField pFld;
            //int iSheetCol;
            //int iWorkSheet = 0;
            try
            {
                OleDbDataAdapter pAdapter = new OleDbDataAdapter();

                foreach (TreeNode pNode in trvwFeatures.Nodes)
                {
                    if (pNode.Nodes.Count == 0) continue;
                    if (!(pNode.Tag is SelectLayerNode)) continue;
                    pArray =(pNode.Tag as SelectLayerNode).Features;
                    if (pArray.Count == 0) continue;
                    if (!(pArray.get_Element(0) is IFeature)) continue;
                    if (((IFeatureClass)((IFeature)pArray.get_Element(0)).Class).FeatureType != esriFeatureType.esriFTSimple) continue;
                    int index = 0;
                    System.Data.DataTable pTable = null;

                    while (index < pArray.Count)
                    {
                        pSrcFeature = pArray.get_Element(index) as IFeature;
                        if (index == 0)
                        {
                            pSrcFcls = pSrcFeature.Class as IFeatureClass;
                            //if (!(pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation || pSrcFcls.FeatureType == esriFeatureType.esriFTSimple)) continue;
                            pTable = CreateTableByFeatureclass(conn, pAdapter, pSrcFcls);

                        }
                        Featrue2DataRow(pTable, pSrcFeature);
                        index++;
                    }//end while     
                    int count = pAdapter.Update(pTable);
                }
            }
            catch (System.Exception ex)
            {
                MsgHelper.ShowInfomationMsgbox("导出出错!" + ex.Message);
                return false;
            }
            finally
            {
                if (conn != null) conn.Close();
            }

            return true;

        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strPath"></param>
        /// <returns></returns>
        private OleDbConnection CreateMDB(string strPath)
        {
            ADOX.Catalog cat = new ADOX.Catalog();
            if (System.IO.File.Exists(strPath) == true) System.IO.File.Delete(strPath);
            string str = "provider=Microsoft.Jet.OleDb.4.0;Data Source=" + strPath;
            cat.Create(str);
            cat = null;
            return new OleDbConnection(str);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="oleConnection"></param>
        /// <param name="pAdater"></param>
        /// <param name="pFcls"></param>
        /// <returns></returns>
        private System.Data.DataTable CreateTableByFeatureclass(OleDbConnection oleConnection, OleDbDataAdapter pAdater, IFeatureClass pFcls)
        {
            System.Data.DataTable pTable = null;
            IFields pFlds = pFcls.Fields;
            string strTableName = ((IDataset)pFcls).Name;
            string strSql = " create table " + strTableName + " (";
            IField pFld;
            string sDataType;
            for (int i = 0; i < pFlds.FieldCount; i++)
            {
                pFld = pFlds.get_Field(i);
                switch (pFld.Type)
                {
                    case esriFieldType.esriFieldTypeDate:
                        sDataType = "DATETIME";
                        strSql += pFld.Name + " " + sDataType + ",";
                        break;
                    case esriFieldType.esriFieldTypeDouble:
                    case esriFieldType.esriFieldTypeSingle:
                        sDataType = "FLOAT";
                        strSql += pFld.Name + " " + sDataType + ",";
                        break;
                    case esriFieldType.esriFieldTypeInteger:
                        sDataType = "INTEGER";
                        strSql += pFld.Name + " " + sDataType + ",";
                        break;
                    case esriFieldType.esriFieldTypeOID:
                        sDataType = "INTEGER";
                        strSql += pFld.Name + " " + sDataType + " primary key,";
                        break;
                    case esriFieldType.esriFieldTypeSmallInteger:
                        sDataType = "INTEGER";
                        strSql += pFld.Name + " " + sDataType + ",";
                        break; ;
                    case esriFieldType.esriFieldTypeString:
                        sDataType = "TEXT";
                        strSql += pFld.Name + " " + sDataType + "(" + pFld.Length + "),";
                        break;
                    default:
                        {
                            break;
                        }
                }
            }
            strSql = strSql.Remove(strSql.Length - 1, 1);
            strSql += ")";
            OleDbCommand pCmd = oleConnection.CreateCommand();
            pCmd.CommandText = strSql;
            pCmd.ExecuteNonQuery();
            pCmd.CommandText = "select *  from " + strTableName;
            OleDbCommandBuilder pCmdBuilder = new OleDbCommandBuilder(pAdater);
            System.Data.DataSet pDataset = new System.Data.DataSet();
            pAdater.SelectCommand = pCmd;
            pAdater.Fill(pDataset, strTableName);
            pTable = pDataset.Tables[strTableName];
            return pTable;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pTable"></param>
        /// <param name="pFeature"></param>
        private void Featrue2DataRow(System.Data.DataTable pTable, IFeature pFeature)
        {
            System.Data.DataRow pRow = pTable.NewRow();
            for (int i = 0; i < pFeature.Fields.FieldCount; i++)
            {
                if (pTable.Columns[pFeature.Fields.get_Field(i).Name] != null)
                {
                    pRow[pFeature.Fields.get_Field(i).Name] = pFeature.get_Value(i);
                }
            }
            pTable.Rows.Add(pRow);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="workBook"></param>
        private static void SaveAs(string FileName, ComObject workBook)
        {
            int pXlFileFormat = -4143;
            string kong1 = "";
            string kong2 = "";
            bool False1 = false;
            bool False2 = false;
            int pXlSaveAsAccessMode = 1;
            int pXlSaveConflictResolution = 2;
            bool False3 = false;
            object null1 = null;
            object null2 = null;
            bool False4 = false;

            object[] objArr = new object[12];
            objArr[0] = FileName;
            objArr[1] = pXlFileFormat;
            objArr[2] = kong1;
            objArr[3] = kong2;
            objArr[4] = False1;
            objArr[5] = False2;
            objArr[6] = pXlSaveAsAccessMode;
            objArr[7] = pXlSaveConflictResolution;
            objArr[8] = False3;
            objArr[9] = null1;
            objArr[10] = null2;
            objArr[11] = False4;

            workBook.InvokeMethod("SaveAs", objArr);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pFwks"></param>
        /// <param name="pSrcFcls"></param>
        /// <returns></returns>
        private IFeatureClass CreateFeatureClass(IFeatureWorkspace pFwks, IFeatureClass pSrcFcls)
        {
            IFeatureClass pFeatureClass;
            IDataset pDataset = pSrcFcls as IDataset;
            string strNewFclsName = pDataset.Name;
            if (strNewFclsName.IndexOf(".") > 0)
            {
                strNewFclsName = strNewFclsName.Substring(strNewFclsName.IndexOf(".") + 1);
                if (strNewFclsName == "") return null;
            }

            int index = 0;
            if (((IWorkspace)pFwks).Type != esriWorkspaceType.esriFileSystemWorkspace)
            {
                while (((IWorkspace2)pFwks).get_NameExists(esriDatasetType.esriDTFeatureClass, strNewFclsName))
                {
                    index++;
                    strNewFclsName += "_" + index;
                }
            }
            else
            {
                while (System.IO.File.Exists(((IWorkspace)pFwks).PathName + "\\" + strNewFclsName + ".shp"))
                {
                    index++;
                    strNewFclsName += "_" + index;
                }
            }
            if (pSrcFcls.FeatureType == esriFeatureType.esriFTAnnotation)
            {
                IAnnotationClassExtension pAnnoFclsExtension = pSrcFcls.Extension as IAnnotationClassExtension;
                pFeatureClass = GeodatabaseHelper.CreateAnnotationFeatureClass((IWorkspace)pFwks, strNewFclsName,
                    ((ESRI.ArcGIS.esriSystem.IClone)pSrcFcls.Fields).Clone() as IFields, pSrcFcls);
            }
            else
            {
                pFeatureClass = pFwks.CreateFeatureClass(strNewFclsName, ((ESRI.ArcGIS.esriSystem.IClone)pSrcFcls.Fields).Clone() as IFields, null, null, pSrcFcls.FeatureType, pSrcFcls.ShapeFieldName, "");
            }
            return pFeatureClass;
        }

        /// <summary>
        /// 获取选择集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            ShowSelect();
        }

        /// <summary>
        /// 显示选中要素
        /// </summary>
        private void ShowSelect()
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                int countSelectedLayer = 0;
                ILayer pSelectedLayer = null;
                trvwFeatures.Nodes.Clear();
                dataGridViewX1.Rows.Clear();
                List<IFeatureLayer> layers = MapHelper.GetAllLayer<IFeatureLayer>(m_Map);
                foreach (IFeatureLayer lyr in layers)
                {
                    if (lyr.Valid)
                    {
                        IFeatureSelection pFeatSelection = lyr as IFeatureSelection;
                        if (pFeatSelection.SelectionSet.Count > 0)
                        {
                            countSelectedLayer++;
                            pSelectedLayer = lyr;
                            AddSeletionSetListToTree(pFeatSelection);
                        }
                    }
                }
                if (countSelectedLayer == 1)
                {
                    SetCurrentLayer(pSelectedLayer);
                }
                else if (countSelectedLayer > 1)
                {
                    layersComboBox1.SelectedIndex = 3;//所有图层
                }
                if (trvwFeatures.Nodes.Count > 0) trvwFeatures.Nodes[0].Expand();
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteLog(ex);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        /// <summary>
        /// 显示节点属性信息
        /// </summary>
        /// <param name="node">要查看的树节点</param>
        private void ShowProperty(TreeNode node)
        {
            if (node.Parent == null) return;
            if (!(node.Parent.Tag is SelectLayerNode)) return;
            int index = node.Parent.Nodes.IndexOf(node);
            IArray pArray = (node.Parent.Tag as SelectLayerNode).Features;
            object element = pArray.get_Element(index);
            if (element is IFeature)
            {
                ShowProperty(element as IFeature);
            }
            else if (element is IPoint)
            {
                ShowRasterPropery(node.Parent.Text, element as IPoint);
            }
            else
            {
                
            }
        }

        /// <summary>
        /// 显示对象的属性
        /// </summary>
        /// <param name="feature">选择的要素对象</param>
        /// <param name="datasetname">要素所在的要素类名称</param>
        private void ShowProperty(IFeature feature, string datasetname = "")
        {
            dataGridViewX1.Rows.Clear();
            IField field = null;            
            int precision = 6;
            for (int i = 0; i < feature.Fields.FieldCount; i++)
            {
                field = feature.Fields.get_Field(i);
                if (field.Type == esriFieldType.esriFieldTypeGeometry) continue;
                DataGridViewRow dgRow = dataGridViewX1.Rows[dataGridViewX1.Rows.Add()];
                bool setvalue = true;
                switch (field.Name.ToUpper())
                {
                    case "SHAPE_AREA":
                    case "SHAPE.AREA":
                        dgRow.Cells[0].Value = "面积";
                        if (feature.Shape.SpatialReference is IGeographicCoordinateSystem)
                        {
                            setvalue = false;
                            Type factoryType = Type.GetTypeFromProgID("esriGeometry.SpatialReferenceEnvironment");
                            System.Object obj = Activator.CreateInstance(factoryType);
                            ISpatialReferenceFactory2 pSRF = obj as ISpatialReferenceFactory2;
                            IProjectedCoordinateSystem2 pPCSout = new ProjectedCoordinateSystem() as IProjectedCoordinateSystem2;
                            pPCSout = (IProjectedCoordinateSystem2)pSRF.CreateProjectedCoordinateSystem(4549);
                            IGeometry geo = feature.ShapeCopy;
                            geo.Project(pPCSout);
                            IArea area = geo as IArea;
                            dgRow.Cells[1].Value = (area.Area).ToString("F2");
                            dgRow.Cells[1].ToolTipText = "近似值，仅供参考！";
                        }
                        break;
                    case "SHAPE.LEN":
                    case "SHAPE_LENGTH":
                        if (feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon || feature.Shape.GeometryType == esriGeometryType.esriGeometryEnvelope)
                        {
                            dgRow.Cells[0].Value = "周长";
                        }
                        else
                        {
                            dgRow.Cells[0].Value = "长度";
                        }
                        if (feature.Shape.SpatialReference is IGeographicCoordinateSystem)
                        {
                            setvalue = false;
                            IUnitConverter cvt = new UnitConverter();
                            dgRow.Cells[1].Value = (cvt.ConvertUnits(double.Parse(feature.get_Value(i).ToString()), esriUnits.esriDecimalDegrees, esriUnits.esriMeters)).ToString("F2");
                            dgRow.Cells[1].ToolTipText = "近似值，仅供参考！";
                        }
                        break;
                    default:
                        string alias = field.AliasName;
                        if (string.IsNullOrWhiteSpace(field.AliasName))
                            alias = RuleConfig.GetImportFieldDescription(field.Name, datasetname);
                        dgRow.Cells[0].Value = alias != "" ? alias : field.Name;
                        break;
                }

                if (feature.get_Value(i) != DBNull.Value && setvalue)
                {
                    dgRow.Cells[1].Value = feature.get_Value(i).ToString();
                    if (field.Type == esriFieldType.esriFieldTypeDouble || field.Type == esriFieldType.esriFieldTypeSingle)
                    {
                        double v = double.Parse(dgRow.Cells[1].Value.ToString());
                        if (precision >= 0)
                            dgRow.Cells[1].Value = v.ToString("F" + precision);
                        else
                            dgRow.Cells[1].Value = v.ToString();
                    }

                    if (field.Name.ToUpper() == fcodeFieldName.ToUpper())
                    {
                        string fcode = feature.get_Value(i).ToString();
                        string fname = "";
                        try
                        {
                            fname = RuleConfig.GetImportFName(fcode, "");
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                        if (fname != "") dgRow.Cells[1].ToolTipText = fname;
                    }
                }
            }
        }

        /// <summary>
        /// 显示栅格数据属性
        /// </summary>
        /// <param name="layerName">图层名称</param>
        /// <param name="point"></param>
        private void ShowRasterPropery(string layerName, IPoint point)
        {
            dataGridViewX1.Rows.Clear();
            ILayer pLayer = GetLayerByName(layerName);
            if (pLayer == null) return;
            IIdentify pIdentify = pLayer as IIdentify;
            IArray pArray = pIdentify.Identify(point);
            if (pArray == null || pArray.Count == 0) return;
            object obj = pArray.get_Element(0);
            IRasterIdentifyObj pRasterIdentifyObj = obj as IRasterIdentifyObj;
            if (pRasterIdentifyObj == null) return;
            DataGridViewRow dgRow = dataGridViewX1.Rows[dataGridViewX1.Rows.Add()];
            dgRow.Cells[0].Value = "像素值";
            dgRow.Cells[1].Value = pRasterIdentifyObj.MapTip;
        }

        /// <summary>
        /// retrieve layer by layer name
        /// </summary>
        /// <param name="strLayerName"></param>
        /// <returns></returns>
        private ILayer GetLayerByName(string strLayerName)
        {
            for (int i = 0; i < m_Map.LayerCount; i++)
            {
                if (m_Map.get_Layer(i).Name == strLayerName && m_Map.get_Layer(i).Valid)
                {
                    return m_Map.get_Layer(i);
                }
            }
            return null;
        }

        /// <summary>
        /// 将选择集添加到结果树中
        /// </summary>
        /// <param name="featureSelection">选择集对象</param>
        private void AddSeletionSetListToTree(IFeatureSelection featureSelection)
        {
            if (featureSelection == null) return ;
            ISelectionSet selSet = featureSelection.SelectionSet;
            if (selSet == null || selSet.Count == 0) return ;
            TreeNode node = trvwFeatures.Nodes.Add((featureSelection as IFeatureLayer).Name + "(" + selSet.Count + ")");            
            IFeatureClass featCls = selSet.Target as IFeatureClass;
            IEnumIDs ids = selSet.IDs;
            IArray array = new ESRI.ArcGIS.esriSystem.Array();
            int id = ids.Next();
            while (id >= 0)
            {
                IFeature feat = featCls.GetFeature(id);
                TreeNode ndFeat = node.Nodes.Add(feat.OID.ToString());
                array.Add(feat);      
                id = ids.Next();                
            }
            node.Tag = new SelectLayerNode() { Features = array, Layer = (featureSelection as IFeatureLayer), Name = (featCls as IDataset).Name };
            Marshal.ReleaseComObject(selSet);
            selSet = null;
            if (trvwFeatures.Nodes.Count > 0)
            {
                trvwFeatures.Nodes[0].Expand();
                if (trvwFeatures.Nodes[0].Nodes.Count > 0)
                {
                    ShowProperty(trvwFeatures.Nodes[0].Nodes[0]);
                }
            }
        }
        
        /// <summary>
        /// 节点坐标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbShowPtsCoord_Click(object sender, EventArgs e)
        {
            if (trvwFeatures.SelectedNode == null) return;
            if (trvwFeatures.SelectedNode.Parent == null) return;
            if (!(trvwFeatures.SelectedNode.Parent.Tag is SelectLayerNode)) return;
            int index = trvwFeatures.SelectedNode.Parent.Nodes.IndexOf(trvwFeatures.SelectedNode);
            IArray array = (trvwFeatures.SelectedNode.Parent.Tag as SelectLayerNode).Features;
            object obj = array.get_Element(index);
            if (obj is IFeature)
            {
                if (m_frmPts == null || m_frmPts.IsDisposed)
                {
                    m_frmPts = new FrmPtsCoord();
                    m_frmPts.Show((m_Application as IFramework).MdiForm);
                }
                else
                {
                    m_frmPts.Visible = true;
                }
                m_frmPts.Hook = (m_Application as IFramework).MapControl.Object;
                m_frmPts.Geometry = ((IFeature)obj).Shape;
                m_frmPts.ShowCoordinates();
            }
            else
            {
                MsgHelper.ShowInfomationMsgbox("请先选择一个元素 ！");
            }
        }

        /// <summary>
        /// 选择的图层节点
        /// </summary>
        private class SelectLayerNode
        {
            /// <summary>
            /// 获取或设置要素类的名称
            /// </summary>
            public string Name { get; set; }

            /// <summary>
            /// 获取或设置选择的要素集合
            /// </summary>
            public IArray Features { get; set; }

            /// <summary>
            /// 获取或设置当前的图层
            /// </summary>
            public ILayer Layer { get; set; }
        }
    }

}